/**
 * @file image_sensor.h
 * @brief
 *
 * Copyright (c) 2022 Bouffalolab team
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.  The
 * ASF licenses this file to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the
 * License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 * License for the specific language governing permissions and limitations
 * under the License.
 *
 */
#ifndef __GC0328_H__
#define __GC0328_H__

#include "image_sensor.h"

static struct image_sensor_command_s gc0328_init_list[] = {
    {0xfe, 0x80},
    {0xfe, 0x80},
    {0xfc, 0x16},
    {0xfc, 0x16},
    {0xfc, 0x16},
    {0xfc, 0x16},

    {0xfe, 0x00},
    {0x4f, 0x00},
    {0x42, 0x00},
    {0x03, 0x00},
    {0x04, 0xc0},
    {0x77, 0x62},
    {0x78, 0x40},
    {0x79, 0x4d},

    {0xfe, 0x01},
    {0x4f, 0x00},
    {0x4c, 0x01},
    {0xfe, 0x00},
    //////////////////////////////
    ///////////AWB///////////
    ////////////////////////////////
    {0xfe, 0x01},
    {0x51, 0x80},
    {0x52, 0x12},
    {0x53, 0x80},
    {0x54, 0x60},
    {0x55, 0x01},
    {0x56, 0x06},
    {0x5b, 0x02},
    {0xb1, 0xdc},
    {0xb2, 0xdc},
    {0x7c, 0x71},
    {0x7d, 0x00},
    {0x76, 0x00},
    {0x79, 0x20},
    {0x7b, 0x00},
    {0x70, 0xFF},
    {0x71, 0x00},
    {0x72, 0x10},
    {0x73, 0x40},
    {0x74, 0x40},
    ////AWB//
    {0x50, 0x00},
    {0xfe, 0x01},
    {0x4f, 0x00},
    {0x4c, 0x01},
    {0x4f, 0x00},
    {0x4f, 0x00},
    {0x4f, 0x00},
    {0x4d, 0x36},
    {0x4e, 0x02},
    {0x4d, 0x46},
    {0x4e, 0x02},
    {0x4e, 0x02},
    {0x4d, 0x53},
    {0x4e, 0x08},
    {0x4e, 0x04},
    {0x4e, 0x04},
    {0x4d, 0x63},
    {0x4e, 0x08},
    {0x4e, 0x08},
    {0x4d, 0x82},
    {0x4e, 0x20},
    {0x4e, 0x20},
    {0x4d, 0x92},
    {0x4e, 0x40},
    {0x4d, 0xa2},
    {0x4e, 0x40},
    {0x4f, 0x01},

    {0x50, 0x88},
    {0xfe, 0x00},
    ////////////////////////////////////////////////
    //////////// BLK //////////////////////
    ////////////////////////////////////////////////
    {0x27, 0x00},
    {0x2a, 0x40},
    {0x2b, 0x40},
    {0x2c, 0x40},
    {0x2d, 0x40},
    //////////////////////////////////////////////
    ////////// page 0 ////////////////////////
    //////////////////////////////////////////////
    {0xfe, 0x00},
    {0x05, 0x00},
    {0x06, 0xde},//h_blank
    {0x07, 0x00},
    {0x08, 0xa7},

    {0x0d, 0x01},
    {0x0e, 0xe8},
    {0x0f, 0x02},
    {0x10, 0x88},
    {0x09, 0x00},
    {0x0a, 0x00},
    {0x0b, 0x00},
    {0x0c, 0x00},
    {0x16, 0x00},
    {0x17, 0x14 | 0x01},    // dir = 0x01
    {0x18, 0x0e},
    {0x19, 0x06},

    {0x1b, 0x48},
    {0x1f, 0xC8},
    {0x20, 0x01},
    {0x21, 0x78},
    {0x22, 0xb0},
    {0x23, 0x06},
    {0x24, 0x11},
    {0x26, 0x00},

    {0x50, 0x01}, // crop mode
    // global gain for range
    {0x70, 0x85},
    ////////////////////////////////////////////////
    //////////// block enable /////////////
    ////////////////////////////////////////////////
    {0x40, 0x7f},
    {0x41, 0x24},
    {0x42, 0xff},
    {0x45, 0x00},
    {0x44, 0x02}, //YUYV
    {0x46, 0x03}, //[0] VSYNC polarity 0x02

    {0x4b, 0x01},
    {0x50, 0x01},
    // DN & EEINTP
    {0x7e, 0x0a},
    {0x7f, 0x03},
    {0x81, 0x15},
    {0x82, 0x85},
    {0x83, 0x02},
    {0x84, 0xe5},
    {0x90, 0xac},
    {0x92, 0x02},
    {0x94, 0x02},
    {0x95, 0x54},
    ///////YCP
    {0xd1, 0x32},
    {0xd2, 0x32},
    {0xdd, 0x58},
    {0xde, 0x36},
    {0xe4, 0x88},
    {0xe5, 0x40},
    {0xd7, 0x0e},
    /////////////////////////////
    //////////////// GAMMA //////
    /////////////////////////////
    // rgb gamma
#if 0   /* RGBGAMMA_test */
    {0xfe, 0x00},
    {0xbf, 0x08},
    {0xc0, 0x10},
    {0xc1, 0x22},
    {0xc2, 0x32},
    {0xc3, 0x43},
    {0xc4, 0x50},
    {0xc5, 0x5e},
    {0xc6, 0x78},
    {0xc7, 0x90},
    {0xc8, 0xa6},
    {0xc9, 0xb9},
    {0xca, 0xc9},
    {0xcb, 0xd6},
    {0xcc, 0xe0},
    {0xcd, 0xee},
    {0xce, 0xf8},
    {0xcf, 0xff},
#elif 1 /* RGBGAMMA_m6 */
    {0xBF, 0x14},
    {0xc0, 0x28},
    {0xc1, 0x44},
    {0xc2, 0x5D},
    {0xc3, 0x72},
    {0xc4, 0x86},
    {0xc5, 0x95},
    {0xc6, 0xB1},
    {0xc7, 0xC6},
    {0xc8, 0xD5},
    {0xc9, 0xE1},
    {0xcA, 0xEA},
    {0xcB, 0xF1},
    {0xcC, 0xF5},
    {0xcD, 0xFB},
    {0xcE, 0xFE},
    {0xcF, 0xFF},
#endif

    /// Y gamma
    {0xfe, 0x00},
    {0x63, 0x00},
    {0x64, 0x05},
    {0x65, 0x0b},
    {0x66, 0x19},
    {0x67, 0x2e},
    {0x68, 0x40},
    {0x69, 0x54},
    {0x6a, 0x66},
    {0x6b, 0x86},
    {0x6c, 0xa7},
    {0x6d, 0xc6},
    {0x6e, 0xe4},
    {0x6f, 0xFF},
    //////ASDE
    {0xfe, 0x01},
    {0x18, 0x02},
    {0xfe, 0x00},
    {0x98, 0x00},
    {0x9b, 0x20},
    {0x9c, 0x80},
    {0xa4, 0x10},
    {0xa8, 0xB0},
    {0xaa, 0x40},
    {0xa2, 0x23},
    {0xad, 0x01},
    //////////////////////////////////////////////
    ////////// AEC ////////////////////////
    //////////////////////////////////////////////
    {0xfe, 0x01},
    {0x9c, 0x02},
    {0x08, 0xa0},
    {0x09, 0xe8},

    {0x10, 0x00},
    {0x11, 0x11},
    {0x12, 0x10},
    // {0x13, 0x80},
    {0x13, 0xB0}, //提高显示的亮度.
    {0x15, 0xfc},
    {0x18, 0x03},
    {0x21, 0xc0},
    {0x22, 0x60},
    {0x23, 0x30},
    {0x25, 0x00},
    {0x24, 0x14},
    //////////////////////////////////////
    ////////////LSC//////////////////////
    //////////////////////////////////////
    // gc0328 Alight lsc reg setting list
    ////Record date: 2013-04-01 15:59:05
    {0xfe, 0x01},
    {0xc0, 0x0d},
    {0xc1, 0x05},
    {0xc2, 0x00},
    {0xc6, 0x07},
    {0xc7, 0x03},
    {0xc8, 0x01},
    {0xba, 0x19},
    {0xbb, 0x10},
    {0xbc, 0x0a},
    {0xb4, 0x19},
    {0xb5, 0x0d},
    {0xb6, 0x09},
    {0xc3, 0x00},
    {0xc4, 0x00},
    {0xc5, 0x0e},
    {0xc9, 0x00},
    {0xca, 0x00},
    {0xcb, 0x00},
    {0xbd, 0x07},
    {0xbe, 0x00},
    {0xbf, 0x0e},
    {0xb7, 0x09},
    {0xb8, 0x00},
    {0xb9, 0x0d},
    {0xa8, 0x01},
    {0xa9, 0x00},
    {0xaa, 0x03},
    {0xab, 0x02},
    {0xac, 0x05},
    {0xad, 0x0c},
    {0xae, 0x03},
    {0xaf, 0x00},
    {0xb0, 0x04},
    {0xb1, 0x04},
    {0xb2, 0x03},
    {0xb3, 0x08},
    {0xa4, 0x00},
    {0xa5, 0x00},
    {0xa6, 0x00},
    {0xa7, 0x00},
    {0xa1, 0x3c},
    {0xa2, 0x50},
    {0xfe, 0x00},
    /// cct
    {0xB1, 0x02},
    {0xB2, 0x02},
    {0xB3, 0x07},
    {0xB4, 0xf0},
    {0xB5, 0x05},
    {0xB6, 0xf0},

    {0xfe, 0x00},
    {0x27, 0xf7},
    {0x28, 0x7F},
    {0x29, 0x20},
    {0x33, 0x20},
    {0x34, 0x20},
    {0x35, 0x20},
    {0x36, 0x20},
    {0x32, 0x08},

    {0x47, 0x00},
    {0x48, 0x00},

    {0xfe, 0x01},
    {0x79, 0x00},
    {0x7d, 0x00},
    {0x50, 0x88},
    {0x5b, 0x04},
    {0x76, 0x8f},
    {0x80, 0x70},
    {0x81, 0x70},
    {0x82, 0xb0},
    {0x70, 0xff},
    {0x71, 0x00},
    {0x72, 0x10},
    {0x73, 0x40},
    {0x74, 0x40},

    {0xfe, 0x00},
    {0x70, 0x45},
    {0x4f, 0x01},
    {0xf1, 0x07},

    {0xf2, 0x01},
    //////////// Set Frame Rate /////////////
    //{0xfe, 0x00},
    //{0x05, 0x00},
    //{0x06, 0x4c}, // HB
    //{0x07, 0x00},
    //{0x08, 0x28}, // VB
    
    //{0xfe, 0x01},
    //{0x29, 0x00},
    //{0x2a, 0x4e}, // step
    //
    //{0x2b, 0x02}, //high 4bit
    //{0x2c, 0x70}, //low 8bit
    //
    //{0x2d, 0x03},
    //{0x2e, 0x0c},
    //
    //{0x2f, 0x05},
    //{0x30, 0x00},
    //
    //{0x31, 0x0f},    //夜间主循环7帧 //高位是4bit，即最大设为0x0f
    //{0x32, 0x00},   //low 8bit
    //
    //{0x33, 0x30},    //4档曝光

    //////////// Set Window /////////////
    //{0xfe, 0x00},
    //{0x59, 0x22}, // subsampleratio=2
    //{0x5a, 0x03},
    //{0x5b, 0x00},
    //{0x5c, 0x00},
    //{0x5d, 0x00},
    //{0x5e, 0x00},
    //{0x5f, 0x00},
    //{0x60, 0x00},
    //{0x61, 0x00},
    //{0x62, 0x00},
    //{0x50, 0x01}, // crop 320x240 //
    //{0x51, 0x00},
    //{0x52, 0x00},
    //{0x53, 0x00},
    //{0x54, 0x00},
    //{0x55, 0x00},
    //{0x56, 0xf0}, // 240
    //{0x57, 0x01},
    //{0x58, 0x40}, // 320

    /* 640*480 */
    {0xfe, 0x00},
    {0x4b, 0x8b},
    //{0x4c, 0x04},//debug mode
    {0x50, 0x01},
    {0x51, 0x00},
    {0x52, 0x00},
    {0x53, 0x00},
    {0x54, 0x00},
    {0x55, 0x01},
    {0x56, 0xe0},
    {0x57, 0x02},
    {0x58, 0x80},
    {0x59, 0x11},
    {0x5a, 0x02},
    {0x5b, 0x00},
    {0x5c, 0x00},
    {0x5d, 0x00},
    {0x5e, 0x00},
    {0x5f, 0x00},
    {0x60, 0x00},
    {0x61, 0x00},
    {0x62, 0x00},
    
    {0xFE, 0x00},
    {0xF1, 0x00},
    {0xF2, 0x00},

    {0x00, 0x00},
    
    {0xFE, 0x00},
    {0xF1, 0x07},
    {0xF2, 0x01},
};

static struct image_sensor_config_s gc0328_config = {
    .name = "GC0328",
    .output_format = IMAGE_SENSOR_FORMAT_YUV422_YUYV,
    .slave_addr = 0x21,
    .id_size = 1,
    .reg_size = 1,
    .h_blank = 0xde,
    .resolution_x = 640,
    .resolution_y = 480,
    .id_addr = 0xf0,
    .id_value = 0x9d,
    .pixel_clock = 24000000,
    .init_list_len = sizeof(gc0328_init_list)/sizeof(gc0328_init_list[0]),
    .init_list = gc0328_init_list,
};

#endif /* __GC0328_H__ */
